package com.harmontronics.hanma.paas.paas.domain.app.service;

import com.harmontronics.hanma.paas.paas.consts.DbConstants;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmScript;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.ScriptContentTypeEnum;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.ScriptTypeEnum;
import lombok.SneakyThrows;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.File;
import java.io.FileReader;
import java.net.URLDecoder;
import java.util.HashMap;

/**
 * @author ldb
 */
public class ServiceTaskScriptSupportDelegate implements JavaDelegate {

    private Expression script;

    @Autowired
    private HmScriptService hmScriptService;


    @Autowired
    private ScriptExecutor scriptExecutor;

    @SneakyThrows
    @Override
    public void execute(DelegateExecution execution) {

        String scriptIdStr = (String) script.getValue(execution);
        Long scriptId = Long.parseLong(scriptIdStr);
        HmScript hmScript = hmScriptService.findById(scriptId);
        if (hmScript.getContentType() == ScriptContentTypeEnum.CODE) {
            String code = URLDecoder.decode(hmScript.getContent(), "UTF-8");
            if (hmScript.getType() == ScriptTypeEnum.JAVASCRIPT) {
                executeJavaScript(execution, code);
            }
            if (hmScript.getType() == ScriptTypeEnum.GROOVY) {
                scriptExecutor.withFlowableExecution(execution).execute(code, new HashMap<>(1));
            }
        }
        if (hmScript.getContentType() == ScriptContentTypeEnum.FILE) {
            Object appUniqueObj = execution.getVariable("appUnique");
            String appUnique = appUniqueObj == null ? DbConstants.DS_MASTER_NAME : appUniqueObj.toString();
            File scriptFile = getScriptFile(appUnique);
            if (hmScript.getType() == ScriptTypeEnum.JAVASCRIPT) {
                ScriptEngineManager manager = new ScriptEngineManager();
                ScriptEngine engine = manager.getEngineByName("JavaScript");
                engine.put("execution", execution);
                engine.eval(new FileReader(new File(scriptFile, hmScript.getContent())));
            }
            if (hmScript.getType() == ScriptTypeEnum.GROOVY) {
                scriptExecutor.withFlowableExecution(execution).execute(new File(scriptFile.getAbsolutePath(), hmScript.getContent()), new HashMap<>(1));
            }
        }
    }


    private File getScriptFile(String appUnique) {
        ApplicationHome home = new ApplicationHome(getClass());
        File homeDir = home.getDir();
        File scriptHomeDir = new File(homeDir, "script");
        return new File(scriptHomeDir, appUnique);

    }

    private void executeJavaScript(DelegateExecution execution, String code) throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        engine.put("execution", execution);
        engine.eval(code);
    }
}
